package com.wn.login.view

import android.content.Context
import android.content.Intent
import android.text.SpannableStringBuilder
import android.text.method.LinkMovementMethod
import android.widget.EditText
import android.widget.TextView
import androidx.activity.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.blankj.utilcode.util.ToastUtils
import com.wn.common.provider.UserServiceProvider
import com.wn.framework.base.BaseActivity
import com.wn.framework.ext.onClick
import com.wn.framework.ext.textChangeFlow
import com.wn.login.utils.stringSetSpan
import com.wn.login.viewmodel.LoginViewModel
import com.wn.mod_login.R
import com.wn.mod_login.databinding.ActivityRegisterBinding
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch

/**
 * @Author: wn
 * @Date: 2025/7/3 17:11
 * @Description: 注册页  12332112332   111111
 */
@AndroidEntryPoint
class RegisterActivity : BaseActivity<ActivityRegisterBinding>() {

  override fun getLayoutRes() = R.layout.activity_register

  private val viewModel by viewModels<LoginViewModel>()

  override fun initView() {
    initAgreement()
    initListener()
  }

  /**
   * 初始化协议 是否勾选
   */
  private fun initAgreement() {
    mBinding.cbAgreement.apply {
      // 我已阅读并同意 《隐私政策》 及 《用户服务协议》
      val agreement = getString(com.wn.framework.R.string.login_agreement)
      val privacySpan = getString(com.wn.framework.R.string.login_privacy_agreement)
      val serviceSpan = getString(com.wn.framework.R.string.login_user_agreement)
      runCatching {
        // 创建一个 SpannableStringBuilder 对象
        val spaBuilder = SpannableStringBuilder(agreement)
        // 启用文本中的超链接点击功能
        movementMethod = LinkMovementMethod.getInstance()
        //《隐私政策》
        stringSetSpan(spaBuilder, privacySpan, this@RegisterActivity)
        // 我已阅读并同意 《隐私政策》 及 《用户服务协议》
        stringSetSpan(spaBuilder, serviceSpan, this@RegisterActivity)
        // 为 CheckBox 重新赋值 文本
        setText(spaBuilder, TextView.BufferType.SPANNABLE)
      }
        .onFailure {
          text = agreement
        }
    }
  }

  /**
   * 初始化监听器
   */
  private fun initListener() {
    mBinding.apply {
      // 勾选框 事件
      cbAgreement.setOnCheckedChangeListener { _, isChecked ->
        updateLoginState(isChecked)
      }
      // 输入框变化 -- 更新 登录按钮 状态
      etPhone.apply { setEditTextChange(this) }
      etPassword.apply { setEditTextChange(this) }
      etRepassword.apply { setEditTextChange(this) }
      // 注册按钮点击事件
      tvRegister.onClick {
        doRegister()
      }
    }
  }

  /**
   * 注册按钮 点击
   */
  private fun doRegister() {
    mBinding.apply {
      val userName = etPhone.text?.trim().let { it.toString() ?: "" }
      val password = etPassword.text?.trim().let { it.toString() ?: "" }
      val repassword = etRepassword.text?.trim().let { it.toString() ?: "" }

      if (userName.isEmpty() || userName.length < 11) {
        ToastUtils.showLong(getString(com.wn.framework.R.string.error_phone_number))
        return
      }
      if (password.isEmpty() || repassword.isEmpty() || password != repassword) {
        ToastUtils.showLong(com.wn.framework.R.string.error_double_password)
        return
      }
      // 不勾选 协议 按纽无法点击 所以这里不需要判断

      // viewModel register
      toDoRegister(userName, password, repassword)
    }

  }

  /**
   * 更新登录按钮状态 -- 勾选框选中时，且  登陆按钮为可点击状态
   */
  private fun updateLoginState(isChecked: Boolean) {
    mBinding.apply {
      val phoneEnable = etPhone.run {
        val phone = text.toString()
        phone.isNotEmpty() && phone.length == 11
      }

      val passwordEnable = etPassword.run {
        val password = text.toString()
        // 重复输入密码
        val repassword = mBinding.etRepassword.text.toString()
        // 值 比较 == , 引用 比较 ===
        password.isNotEmpty() && repassword.isNotEmpty() && password == repassword
      }
      // 更新 登陆按钮 状态
      tvRegister.isSelected = phoneEnable && passwordEnable && isChecked
      tvRegister.isEnabled = phoneEnable && passwordEnable && isChecked
    }
  }

  /**
   * 设置 EditText 文本变化监听
   * @param editText EditText
   */
  @OptIn(FlowPreview::class)
  private fun setEditTextChange(editText: EditText) {
    editText.textChangeFlow()
//      .filter { it.isNotEmpty() } // 过滤空内容 后面需要对此进行 判空，此处不过滤
      .debounce(300) // 300ms防抖
      .flowOn(Dispatchers.IO) // 在 IO 线程执行
      .onEach {
        // 更新登录按钮状态
        updateLoginState(mBinding.cbAgreement.isChecked)
      }
      .launchIn(lifecycleScope) // 在生命周期范围内收集流 终止操作符  一般搭配 onEach 一起使用
  }

  private lateinit var job: Job
  private fun toDoRegister(userName: String, password: String, repassword: String) {
    if (::job.isInitialized) job.cancel()
    job = lifecycleScope.launch {
      lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
        // 注册
        launch {
          viewModel.register(userName, password, repassword).collect {
            it ?: return@collect
            /**
             * 成功提示
             * 保存 账号 + 用户信息
             * 关闭当前页
             */
            ToastUtils.showLong(com.wn.framework.R.string.success_register)
            UserServiceProvider.saveUserInfo(it)
            UserServiceProvider.saveUserPhone(it.username)
            finish()
          }
        }

        // 加载 loading
        launch {
          viewModel.loading.collect {
            if (it) showLoading() else dismissLoading()
          }
        }
      }
    }
  }

  companion object {
    /**
     * 跳转到登录页面
     * @param context Context
     */
    fun toRegister(context: Context) {
      val intent = Intent(context, RegisterActivity::class.java)
      context.startActivity(intent)
    }
  }

  /**
   * Home键或者锁屏 后 如果不 cancel 返回时数据会重复请求  -- stop
   * viewPager 滑动 -- pause
   */
  override fun onStop() {
    if (::job.isInitialized) job.cancel()
    super.onStop()
  }
}